package exercise.jslide.jslide.model.image;

import exercise.jslide.jslide.model.SlideElement;
import exercise.jslide.jslide.utils.EdgePoint;
import javafx.geometry.Point2D;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.image.Image;
import javafx.scene.paint.Color;

import java.io.FileInputStream;
import java.io.FileNotFoundException;


public class ImageElement extends SlideElement {
    protected boolean isSelected;
    private String fileName;
    private String filePath;

    public EdgePoint getEdgePoint() {
        return edgePoint;
    }

    private EdgePoint edgePoint;



    public ImageElement() {
        edgePoint = EdgePoint.noPoint;
    }


    @Override
    public void draw(GraphicsContext gc) {
        gc.save();
        drawImage(gc);
        if (isSelected) {
            drawSelectionFrame(gc);
            drawControlPoints(gc);
        }
        gc.restore();

    }

    protected void drawImage(GraphicsContext gc) {

        try {
            gc.drawImage(new Image(new FileInputStream(getFilePath()+getFileName())), x, y, width, height);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }

    }

    protected void drawSelectionFrame(GraphicsContext gc) {
        gc.setStroke(Color.BLUE); // 设置选择框颜色为蓝色
        gc.setLineDashes(5); // 设置虚线
        gc.strokeRect(x - 2, y - 2, width + 4, height + 4); // 绘制虚线框
        gc.setLineDashes(null); // 取消虚线
    }

    protected void drawControlPoints(GraphicsContext gc) {
        final double SIZE = 4; // 控制点大小
        gc.setFill(Color.WHITE); // 控制点填充色
        gc.setStroke(Color.BLUE); // 控制点边界色

        // 8个控制点的位置
        Point2D[] points = {
                new Point2D(x, y),                    // 左上
                new Point2D(x + width / 2, y),          // 上中
                new Point2D(x + width, y),            // 右上
                new Point2D(x + width, y + height / 2), // 右中
                new Point2D(x + width, y + height),   // 右下
                new Point2D(x + width / 2, y + height), // 下中
                new Point2D(x, y + height),           // 左下
                new Point2D(x, y + height / 2)          // 左中
        };

        for (Point2D p : points) {
            gc.fillRect(p.getX() - SIZE / 2, p.getY() - SIZE / 2, SIZE, SIZE);
            gc.strokeRect(p.getX() - SIZE / 2, p.getY() - SIZE / 2, SIZE, SIZE);
        }
    }

    public void setEdgePoint(Point2D point){
        if(point.getX()>x+width-3 && point.getX()<=x+width+3 && point.getY()>y+height/2-3 && point.getY()<=y+height/2+3){
            edgePoint = EdgePoint.RightMid;
        }
        else if(point.getX()<x+3 && point.getX()>=x-3 && point.getY()>y+height/2-3 && point.getY()<=y+height/2+3){
            edgePoint = EdgePoint.LeftMid;
        }
        else if(point.getY()>y+height-3 && point.getY()<=y+height+3 && point.getX()>x+width/2-3 && point.getX()<=x+width/2+3){
            edgePoint = EdgePoint.MidDown;
        }
        else if(point.getY()<y+3 && point.getY()>=y-3 && point.getX()>x+width/2-3 && point.getX()<=x+width/2+3){
            edgePoint = EdgePoint.MidUp;
        } else if (point.getX()<x+3 && point.getX()>=x-3 && point.getY()<y+3 && point.getY()>=y-3) {
            edgePoint = EdgePoint.LeftUp;
        }
        else if(point.getX()>x+width-3 && point.getX()<=x+width+3 && point.getY()<y+3 && point.getY()>=y-3){
            edgePoint = EdgePoint.RightUP;
        }
        else if(point.getX()<x+3 && point.getX()>=x-3 && point.getY()>y+height-3 && point.getY()<=y+height+3){
            edgePoint = EdgePoint.LeftDown;
        }
        else if(point.getX()>x+width-3 && point.getX()<=x+width+3 && point.getY()>y+height-3 && point.getY()<=y+height+3){
            edgePoint = EdgePoint.RightDown;
        }
        else {
            edgePoint = EdgePoint.noPoint;
        }
//        System.out.println(edgePoint);
    }

    public void reSize(double deltaX,double deltaY){
        if(edgePoint == EdgePoint.noPoint){

        }
        if(edgePoint == EdgePoint.MidDown){
            height = height+deltaY;
        }
        if(edgePoint == EdgePoint.MidUp){
            y = y+deltaY;
            height = height-deltaY;
        }
        if(edgePoint == EdgePoint.LeftMid){
            x = x+deltaX;
            width = width-deltaX;
        }
        if(edgePoint == EdgePoint.RightMid){
            width = width+deltaX;
        }
        if(edgePoint == EdgePoint.LeftUp){
            x = x+deltaX;
            width = width-deltaX;
            y = y+deltaY;
            height = height-deltaY;
        }
        if(edgePoint == EdgePoint.LeftDown){
            height = height+deltaY;
            x = x+deltaX;
            width = width-deltaX;
        }
        if(edgePoint == EdgePoint.RightDown){
            height = height+deltaY;
            width = width+deltaX;
        }
        if(edgePoint == EdgePoint.RightUP){
            y = y+deltaY;
            height = height-deltaY;
            width = width+deltaX;
        }

    }


    @Override
    public boolean contains(Point2D point) {
        double tolerance = 2.0;
        if (point.getX() >= x-tolerance && point.getX() <= x + width+tolerance && point.getY() >= y-tolerance && point.getY() <= y + height+tolerance) {
            return true;
        }
        else if(point.getX() <= x-tolerance && point.getX() >= x + width+tolerance && point.getY() <= y-tolerance && point.getY() >= y + height+tolerance){
            return true;
        }
        else if(point.getX() >= x-tolerance && point.getX() <= x + width+tolerance && point.getY() <= y-tolerance && point.getY() >= y + height+tolerance){
            return true;
        }
        else if(point.getX() <= x-tolerance && point.getX() >= x + width+tolerance && point.getY() >= y-tolerance && point.getY() <= y + height+tolerance){
            return true;
        }
        else {
            return false;
        }
    }

    @Override
    public SlideElement clone() {
        ImageElement imageElement = new ImageElement();
        imageElement.setX(x);
        imageElement.setY(y);
        imageElement.setWidth(width);
        imageElement.setHeight(height);
        imageElement.setFileName(fileName);
        imageElement.setFilePath(filePath);
        return imageElement;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public String getFileName() {
        return this.fileName;
    }

    public void setFilePath(String filePath) {
        this.filePath = filePath;
    }

    public String getFilePath() {
        return this.filePath;
    }
//    public reSize
}
